<script setup lang="ts">
import { computed, nextTick, onMounted, ref, watch } from 'vue';
import { useForm } from '@sa/alova/client';
import WangEditor from 'wangeditor';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { createArticle, updateArticle } from '@/service/api/cms';
import { $t } from '@/locales';

defineOptions({
  name: 'ArticleDrawer'
});

const editor = ref<WangEditor>();
const domRef = ref<HTMLElement>();

function renderWangEditor() {
  try {
    // Destroy existing editor if any
    if (editor.value) {
      editor.value.destroy();
      editor.value = undefined;
    }

    // Ensure DOM element is available
    if (!domRef.value) {
      console.error('WangEditor DOM element not found');
      return;
    }

    editor.value = new WangEditor(domRef.value);
    setEditorConfig();
    editor.value.create();
  } catch (error) {
    console.error('Failed to initialize WangEditor:', error);
  }
}

function setEditorConfig() {
  if (editor.value?.config?.zIndex) {
    editor.value.config.zIndex = 10;
  }
}

function destroyEditor() {
  if (editor.value) {
    try {
      editor.value.destroy();
      editor.value = undefined;
    } catch (error) {
      console.error('Failed to destroy WangEditor:', error);
    }
  }
}

onMounted(() => {
  // Editor will be initialized when drawer opens
});

interface Props {
  /** the type of operation */
  operateType: NaiveUI.TableOperateType;
  /** the edit row data */
  rowData?: Api.Model | null;
}

const props = defineProps<Props>();

interface Emits {
  (e: 'submitted'): void;
}

const emit = defineEmits<Emits>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule } = useFormRules();

const title = computed(() => {
  const titles: Record<NaiveUI.TableOperateType, string> = {
    add: '新增文章',
    edit: '编辑文章'
  };
  return titles[props.operateType];
});

const {
  loading: submitting,
  reset,
  send: submit,
  form,
  updateForm
} = useForm(formData => (props.operateType === 'add' ? createArticle(formData) : updateArticle(formData)), {
  initialForm: {} as Api.Model,
  resetAfterSubmitting: true
});

type RuleKey = Extract<keyof Api.Model, 'userName' | 'status'>;

const rules: Record<RuleKey, App.Global.FormRule> = {
  userName: defaultRequiredRule,
  status: defaultRequiredRule
};

function handleInitModel() {
  if (props.operateType === 'edit' && props.rowData) {
    updateForm(props.rowData);
    // Set editor content after form data is updated
    nextTick(() => {
      if (editor.value && props.rowData?.content) {
        editor.value.txt.html(props.rowData.content);
      }
    });
  } else if (props.operateType === 'add') {
    reset();
    // Clear editor content for new article
    nextTick(() => {
      if (editor.value) {
        editor.value.txt.html('');
      }
    });
  }
}

function closeDrawer() {
  visible.value = false;
}

async function handleSubmit() {
  // Capture editor content before submitting
  if (editor.value) {
    // Use type assertion to avoid TypeScript error
    (form.value as any).content = editor.value.txt.html();
  }

  await validate();
  // request
  await submit();
  window.$message?.success($t('common.updateSuccess'));
  closeDrawer();
  emit('submitted');
}

watch(visible, newVisible => {
  if (newVisible) {
    // Initialize editor when drawer opens
    nextTick(() => {
      renderWangEditor();
    });
    restoreValidation();
    handleInitModel();
  } else {
    // Destroy editor when drawer closes
    destroyEditor();
  }
});

const url = ref('/cms/column/tree?status=1');
function changeSite(value: Array<string | number> | string | number | null) {
  if (value) {
    url.value = `/cms/column/tree?status=1&siteId=${value}`;
  } else {
    url.value = '/cms/column/tree?status=1';
  }
  // Reset parentId when site changes to avoid invalid selections
  form.value.parentId = 0;
}

const attachmentRef = ref<any>();
const thumbnailRef = ref<any>();
</script>

<template>
  <NDrawer v-model:show="visible" display-directive="show" width="100%" class="h-full">
    <NDrawerContent :title="title" :native-scrollbar="false" closable>
      <NForm ref="formRef" :model="form" :rules="rules" label-placement="left" label-width="auto">
        <NSplit :size="0.8" class="h-full" pane1-class="pr-2" pane2-class="pl-2" :resize-trigger-size="0">
          <template #1>
            <NFormItem label="标题" path="title">
              <NInput v-model:value="form.title" placeholder="请输入文章标题" />
            </NFormItem>

            <NFormItem label="内容" path="content">
              <div ref="domRef" class="editor-container w-full bg-white dark:bg-dark"></div>
            </NFormItem>
            <NFormItem label="关键字" path="keywords">
              <NInput v-model:value="form.keywords" placeholder="请输入文章关键字" />
            </NFormItem>
            <NFormItem label="摘要" path="summary">
              <NInput v-model:value="form.summary" type="textarea" placeholder="请输入文章摘要" />
            </NFormItem>
            <NFormItem label="题图" path="thumbnail">
              <PorUpload
                ref="thumbnailRef"
                v-model:value="form.thumbnail"
                action="/infra/storage/storageFile/uploadFile"
                :max="1"
              >
                <NButton>选择文件</NButton>
              </PorUpload>
            </NFormItem>
          </template>
          <template #2>
            <NFormItem label="站点" path="siteId">
              <PorSelect
                v-model:value="form.siteId"
                placeholder="请选择站点"
                url="/cms/site/simpleList?status=1"
                label-field="name"
                value-field="id"
                value-to-number
                filterable
                size="small"
                clearable
                @update:value="changeSite"
              ></PorSelect>
            </NFormItem>
            <NFormItem label="栏目" path="columnId">
              <PorTreeSelect v-model:value="form.columnId" :url="url" value-to-number clearable></PorTreeSelect>
            </NFormItem>
            <NFormItem label="副标题" path="subTitle">
              <NInput v-model:value="form.subTitle" placeholder="请输入文章副标题" />
            </NFormItem>
            <NFormItem label="作者" path="author">
              <NInput v-model:value="form.author" placeholder="请输入作者" />
            </NFormItem>
            <NFormItem label="文章标识" path="slug">
              <NInput v-model:value="form.slug" placeholder="请输入文章标识" />
            </NFormItem>
            <NFormItem label="状态" path="status">
              <NInput v-model:value="form.status" placeholder="请输入文章状态" />
            </NFormItem>
            <NFormItem label="SEO 标题" path="seoTitle">
              <NInput v-model:value="form.seoTitle" placeholder="请输入 SEO 标题" />
            </NFormItem>
            <NFormItem label="SEO 关键字" path="seoKeyword">
              <NInput v-model:value="form.seoKeyword" placeholder="请输入 SEO 关键字" />
            </NFormItem>
            <NFormItem label="SEO 描述" path="seoDescription">
              <NInput v-model:value="form.seoDescription" placeholder="请输入 SEO 描述" />
            </NFormItem>
            <NFormItem label="附件" path="attachment">
              <PorUpload
                ref="attachmentRef"
                v-model:value="form.attachment"
                action="/infra/storage/storageFile/uploadFile"
                :max="1"
              >
                <NButton>选择文件</NButton>
              </PorUpload>
            </NFormItem>
          </template>
        </NSplit>
      </NForm>
      <template #footer>
        <NSpace :size="16">
          <NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
          <NButton type="primary" :loading="submitting" @click="handleSubmit">{{ $t('common.confirm') }}</NButton>
        </NSpace>
      </template>
    </NDrawerContent>
  </NDrawer>
</template>

<style scoped>
:deep(.w-e-toolbar) {
  background: inherit !important;
  border-color: #999 !important;
}

:deep(.w-e-text-container) {
  background: inherit;
  border-color: #999 !important;
}
</style>
